﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.XPath;
using Procure.Data.Context;
using System.Xml;
using System.Web.Security;

namespace Procure.Library
{
    public class procure
    {
        #region enum CartUpdateMode
        private enum CartUpdateMode
        {
            None = 0,
            AddToCart = 1,
            UpdateCartItem = 2,
            UpdateCartItems = 3,
            RemoveCartItem = 4,
            ClearCart = 5
        }
        #endregion

        #region Cart
        #region GetCurrentCart
        public static XPathNodeIterator GetCurrentCart()
        {
            CommerceHelper helper = new CommerceHelper();
            Cart cart = helper.GetCurrentCart();
            try
            {
                if (cart != null)
                {
                    return XmlConverter.ToXPathNavigator(cart).Select("/cart");
                }
            }
            catch { }
            return GetErrorXPathNavigator("Unable to retrieve the current cart");
        }
        #endregion

        #region ProcessCart
        public static void ProcessCart()
        {
            System.Web.HttpContext.Current.Trace.Write("procure", "Processing Cart");
            CommerceHelper helper = new CommerceHelper();

            switch (GetCartUpdateMode())
            {
                case CartUpdateMode.AddToCart:
                    System.Web.HttpContext.Current.Trace.Write("procure", "  Adding Product To Cart");
                    helper.AddToCart();
                    break;

                case CartUpdateMode.UpdateCartItem:
                    System.Web.HttpContext.Current.Trace.Write("procure", "  Updating Item In Cart");
                    helper.UpdateCartItem();
                    break;

                case CartUpdateMode.UpdateCartItems:
                    System.Web.HttpContext.Current.Trace.Write("procure", "  Adding All Items In Cart");
                    helper.UpdateCartItems();
                    break;

                case CartUpdateMode.RemoveCartItem:
                    System.Web.HttpContext.Current.Trace.Write("procure", "  Removing Item From Cart");
                    helper.RemoveCartItem();
                    break;

                case CartUpdateMode.ClearCart:
                    System.Web.HttpContext.Current.Trace.Write("procure", "  Clearing Cart");
                    helper.ClearCart();
                    break;

                default:
                    System.Web.HttpContext.Current.Trace.Write("procure", "  No Action To Take On Cart");
                    break;
            }
        }
        #endregion

        #region GetCartUpdateMode
        private static CartUpdateMode GetCartUpdateMode()
        {
            // several different buttons could initiate this event
            // Add To Cart - detect by the presence of an input named 'i'
            // Update Cart Item - detect by a value being in an input name starting with 'update'
            // Update All Cart Items - detect by a value being in an input named 'updateAll'
            // Remove Cart Item - detect by a value being in an input name starting with 'remove'
            // Clear Cart - detect by a value being in an input named 'clear'
            System.Web.HttpRequest Request = System.Web.HttpContext.Current.Request;
            CartUpdateMode mode = CartUpdateMode.None;
            CommerceHelper helper = new CommerceHelper();

            string[] keys = Request.Params.AllKeys;
            string removeAction = helper.GetActionButtonName(helper.RemoveInputName);
            string updateAction = helper.GetActionButtonName(helper.UpdateInputName);

            if (keys.Contains(helper.AddToCartInputName) && !string.IsNullOrEmpty(Request[helper.AddToCartInputName]))
                mode = CartUpdateMode.AddToCart;
            else if (!string.IsNullOrEmpty(updateAction))
                mode = CartUpdateMode.UpdateCartItem;
            else if (keys.Contains(helper.UpdateAllInputName) && !string.IsNullOrEmpty(Request[helper.UpdateAllInputName]))
                mode = CartUpdateMode.UpdateCartItems;
            else if (!string.IsNullOrEmpty(removeAction))
                mode = CartUpdateMode.RemoveCartItem;
            else if (keys.Contains(helper.ClearInputName) && !string.IsNullOrEmpty(Request[helper.ClearInputName]))
                mode = CartUpdateMode.ClearCart;

            return mode;
        }
        #endregion

        #region Input Names
        public static string GetUpdateButtonName(int productId)
        {
            CommerceHelper helper = new CommerceHelper();
            return string.Format("{0}{1}", helper.UpdateInputName, productId);
        }
        public static string GetRemoveButtonName(int productId)
        {
            CommerceHelper helper = new CommerceHelper();
            return string.Format("{0}{1}", helper.RemoveInputName, productId);
        }

        public static string GetQuantityInputName(int productId)
        {
            CommerceHelper helper = new CommerceHelper();
            return string.Format("{0}{1}", helper.QuantityInputName, productId);
        }

        public static string GetProductIdInputName(int productId)
        {
            CommerceHelper helper = new CommerceHelper();
            return string.Format("{0}{1}", helper.ProductIdInputName, productId);
        }

        public static string GetAddToCartInputName(int productId)
        {
            CommerceHelper helper = new CommerceHelper();
            return helper.AddToCartInputName;
        }

        public static string GetUpdateAllButtonName()
        {
            CommerceHelper helper = new CommerceHelper();
            return helper.UpdateAllInputName;
        }

        public static string GetClearButtonName()
        {
            CommerceHelper helper = new CommerceHelper();
            return helper.ClearInputName;
        }
        #endregion
        #endregion

        #region Product
        public static XPathNodeIterator GetProduct(Int32 ProductId)
        {
            ProcureDataContext context = DataFactory.GetDataContext();
            Product product = context.Products.FirstOrDefault(p => p.Id == ProductId);
            
            try
            {
                if (product != null)
                {
                    return XmlConverter.ToXPathNavigator(product).Select("/product");
                }
            }
            catch
            {
                
            }

            return GetErrorXPathNavigator(string.Format("No Product is matching '{0}'", ProductId));
        }
        #endregion

        #region GetErrorXPathNavigator
        private static XPathNodeIterator GetErrorXPathNavigator(string errorString)
        {
            XmlDocument xd = new XmlDocument();
            xd.LoadXml(string.Format("<error>{0}</error>", errorString));
            return xd.CreateNavigator().Select("/");
        }
        #endregion
    }
}
